package com.da.demo.security.controller;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.da.common.constant.DailyConstant;
import com.da.common.enums.ResultEnum;
import com.da.common.exception.BusinessException;
import com.da.common.exception.ParameterException;
import com.da.common.utils.DailyAimResult;
import com.da.common.utils.PhoneUtils;
import com.da.common.utils.SnowflakeIdWorker;
import com.da.common.utils.TimestampUtil;
import com.da.demo.security.entity.*;

import com.da.demo.security.entity.dto.DailyUsersDTO;
import com.da.demo.security.mapper.DailyRoleMapper;
import com.da.demo.security.mapper.DailySaltUserMapper;
import com.da.demo.security.mapper.DailyUserRolesMapper;
import com.da.demo.security.mapper.DailyUsersMapper;
import com.da.demo.utils.LoginInfoUtil;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.crypto.SecretKey;
import java.security.Principal;
import java.sql.Time;
import java.util.List;
import java.util.Optional;

/**
 * @Author: hyacinth
 * @CreateTime: 2025-02-21
 * @Version: 1.0
 */
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
@Slf4j
public class UserController {

    private final DailyUsersMapper dailyUsersMapper;
    private final DailySaltUserMapper dailySaltUserMapper;

    private final DailyUserRolesMapper dailyUserRolesMapper;

    @PostMapping("/addUser")
    @Transactional
    public DailyAimResult<?> addUser(@RequestBody DailyUsersDTO dailyUsersDTO) {
        Optional.ofNullable(dailyUsersDTO).orElseThrow(() -> new ParameterException(ResultEnum.FAIL.getCode(), "用户信息不能为空"));
        try{
            DailyUsers dailyUsers = new DailyUsers();
            BeanUtils.copyProperties(dailyUsersDTO, dailyUsers);
            dailyUsers.setStatus(DailyConstant.ACTIVE);
            log.info("dailyUsers:{}", JSON.toJSONString(dailyUsers));
            // 对密码进行加密处理
            String password = dailyUsers.getPassword();
            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
            String encodePassword = bCryptPasswordEncoder.encode(password);
            dailyUsers.setPassword(encodePassword);

            // 对电话号码进行加密处理
            String phoneNumber = dailyUsers.getPhoneNumber();
            SecretKey secretKey = PhoneUtils.generateKey();
            String encryptedPhoneNumber = PhoneUtils.encrypt(phoneNumber, secretKey);
            dailyUsers.setPhoneNumber(encryptedPhoneNumber);
            dailyUsers.setCreatedAt(TimestampUtil.now());

            // 生成对应的用户id
            dailyUsers.setUserId("daily" + SnowflakeIdWorker.generateId());
            dailyUsersMapper.insert(dailyUsers);

            // 将对应的电话加密的密钥存储
            DailySaltUser dailySaltUser = new DailySaltUser();
            dailySaltUser.setId(String.valueOf(SnowflakeIdWorker.generateId()));
            dailySaltUser.setUserid(dailyUsers.getId());
            dailySaltUser.setSalt(secretKey.toString());
            dailySaltUser.setCreatedAt(TimestampUtil.now());
            dailySaltUserMapper.insert(dailySaltUser);

            if (!CollectionUtils.isEmpty(dailyUsersDTO.getRoleIdList())){
                DailyUserRoles dailyUserRoles = new DailyUserRoles();
                for (String roleId : dailyUsersDTO.getRoleIdList()) {
                    dailyUserRoles.setId(String.valueOf(SnowflakeIdWorker.generateId()));
                    dailyUserRoles.setUserId(dailyUsers.getId());
                    dailyUserRoles.setRoleId(roleId);
                    dailyUserRoles.setCreatedTime(TimestampUtil.now());
                    dailyUserRolesMapper.insert(dailyUserRoles);
                }
            }
            return DailyAimResult.success("创建用户成功");
        }catch (Exception e){
            log.error("createUser error:{}", e.getMessage());
            throw new BusinessException(ResultEnum.FAIL.getCode(), "创建用户失败");
        }
    }


    @RequestMapping(value = "/toWelcome")
    @ResponseBody
    public ModelAndView index() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("welcome");
        return modelAndView;
    }

    @RequestMapping(value = "/toLogin")
    public ModelAndView toLogin() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("login");
        return modelAndView;
    }

    @RequestMapping(value = "/welcome")
    public @ResponseBody Object welcome(Principal principal) { //@ResponseBody注解，表示方法返回字符串或者json
        //如何拿到登录人的完整信息，比如userId、phone、email、loginAct ......
        return principal;
    }

    @RequestMapping(value = "/welcome2")
    public @ResponseBody Object welcome2(Authentication authentication) { //@ResponseBody注解，表示方法返回字符串或者json
        //如何拿到登录人的完整信息，比如userId、phone、email、loginAct ......
        return authentication;
    }

    @RequestMapping(value = "/welcome3")
    public @ResponseBody Object welcome3(UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken) { //@ResponseBody注解，表示方法返回字符串或者json
        //如何拿到登录人的完整信息，比如userId、phone、email、loginAct ......
        return usernamePasswordAuthenticationToken;
    }

    @RequestMapping(value = "/welcome4")
    public @ResponseBody Object welcome4() { //@ResponseBody注解，表示方法返回字符串或者json
        //如何拿到登录人的完整信息，比如userId、phone、email、loginAct ......
        return SecurityContextHolder.getContext().getAuthentication();
    }

    @RequestMapping(value = "/welcome5")
    public @ResponseBody Object welcome5() { //@ResponseBody注解，表示方法返回字符串或者json
        //如何拿到登录人的完整信息，比如userId、phone、email、loginAct ......
        return LoginInfoUtil.getCurrentLoginUser();
    }

    @RequestMapping(value = "/test")
    public @ResponseBody Object test() { //@ResponseBody注解，表示方法返回字符串或者json
        //如何拿到登录人的完整信息，比如userId、phone、email、loginAct ......
        User2 user2 = new User2();
        return user2; //底层使用jackson把user2对象转成json
    }

}
